package ginRoute

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"path/filepath"
	"utilsx/tools/logUtils"
)

type GinEngine struct {
	engine    *gin.Engine
	namespace map[string][]*Route // namespace name AND RouteTree
}

func NewDefaultEngine() *GinEngine {
	return &GinEngine{
		engine:    gin.Default(),
		namespace: make(map[string][]*Route),
	}
}

func (e *GinEngine) GetEngine() *gin.Engine {
	return e.engine
}
func (e *GinEngine) RootNameSpace(namespace string, routes ...*Route) *GinEngine {
	e.namespace[namespace] = routes
	group := e.engine.Group(namespace)
	for _, route := range routes {
		e.routeHandle(group, route)
	}
	return e
}
func (e *GinEngine) routeHandle(ginGroup *gin.RouterGroup, route *Route) {
	if route.children != nil && len(route.children) > 0 {
		routerGroup := ginGroup.Group(route.path)
		for _, childRoute := range route.children {
			e.routeHandle(routerGroup, childRoute)
		}
	}
	for method, handle := range route.handleFunMap {
		switch method {
		//http.GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE
		case http.MethodGet:
			ginGroup.GET(route.path, handle...)
		case http.MethodHead:
			ginGroup.HEAD(route.path, handle...)
		case http.MethodPost:
			ginGroup.POST(route.path, handle...)
		case http.MethodPut:
			ginGroup.PUT(route.path, handle...)
		case http.MethodPatch:
			ginGroup.PATCH(route.path, handle...)

		case http.MethodDelete:
			ginGroup.DELETE(route.path, handle...)

		case http.MethodOptions:
			ginGroup.OPTIONS(route.path, handle...)
		}
	}
}

func (e *GinEngine) UseMiddleware(middleware ...gin.HandlerFunc) *GinEngine {
	e.engine.Use(middleware...)
	return e
}
func (e *GinEngine) SetStaticPath(webRelativePath, relativeDir string) *GinEngine {
	e.engine.Static(webRelativePath, filepath.Dir(relativeDir))
	return e
}

func (e *GinEngine) RunEngine(port string) {
	e.engine.RedirectTrailingSlash = false
	err := e.engine.Run(port)
	if err != nil {
		logUtils.LogPrintln(1, "Gin Run Fail"+port)
		return
	}
}

func (e *GinEngine) ListenAndServe(port string) {
	err := http.ListenAndServe(port, e.engine.Handler())
	if err != nil {
		return
	}
}
